home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / os2 / e33el2.zip / emacs / 19.33 / lisp / decipher.el < prev    next >
Lisp/Scheme  |  1996-08-04  |  44KB  |  1,052 lines

  1. ;;; decipher.el --- Cryptanalyze monoalphabetic substitution ciphers
  2. ;;
  3. ;; Copyright (C) 1995, 1996 Free Software Foundation, Inc.
  4. ;;
  5. ;; Author: Christopher J. Madsen <ac608@yfn.ysu.edu>
  6. ;; Keywords: games
  7. ;;
  8. ;; This file is part of GNU Emacs.
  9. ;;
  10. ;; GNU Emacs is free software; you can redistribute it and/or modify
  11. ;; it under the terms of the GNU General Public License as published by
  12. ;; the Free Software Foundation; either version 2, or (at your option)
  13. ;; any later version.
  14. ;;
  15. ;; GNU Emacs is distributed in the hope that it will be useful,
  16. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18. ;; GNU General Public License for more details.
  19. ;;
  20. ;; You should have received a copy of the GNU General Public License
  21. ;; along with GNU Emacs; see the file COPYING.  If not, write to the
  22. ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  23. ;; Boston, MA 02111-1307, USA.
  24.  
  25. ;;; Quick Start:
  26. ;;
  27. ;; To decipher a message, type or load it into a buffer and type
  28. ;; `M-x decipher'.  This will format the buffer and place it into
  29. ;; Decipher mode.  You can save your work to a file with the normal
  30. ;; Emacs save commands; when you reload the file it will automatically
  31. ;; enter Decipher mode.
  32. ;;
  33. ;; I'm not going to discuss how to go about breaking a cipher; try
  34. ;; your local library for a book on cryptanalysis.  One book you might
  35. ;; find is:
  36. ;;   Cryptanalysis:  A study of ciphers and their solution
  37. ;;   Helen Fouche Gaines
  38. ;;   ISBN 0-486-20097-3
  39.  
  40. ;;; Commentary:
  41. ;;
  42. ;; This package is designed to help you crack simple substitution
  43. ;; ciphers where one letter stands for another.  It works for ciphers
  44. ;; with or without word divisions.  (You must set the variable
  45. ;; decipher-ignore-spaces for ciphers without word divisions.)
  46. ;;
  47. ;; First, some quick definitions:
  48. ;;   ciphertext   The encrypted message (what you start with)
  49. ;;   plaintext    The decrypted message (what you are trying to get)
  50. ;;
  51. ;; Decipher mode displays ciphertext in uppercase and plaintext in
  52. ;; lowercase.  You must enter the plaintext in lowercase; uppercase
  53. ;; letters are interpreted as commands.  The ciphertext may be entered
  54. ;; in mixed case; `M-x decipher' will convert it to uppercase.
  55. ;;
  56. ;; Decipher mode depends on special characters in the first column of
  57. ;; each line.  The command `M-x decipher' inserts these characters for
  58. ;; you.  The characters and their meanings are:
  59. ;;   (   The plaintext & ciphertext alphabets on the first line
  60. ;;   )   The ciphertext & plaintext alphabets on the second line
  61. ;;   :   A line of ciphertext (with plaintext below)
  62. ;;   >   A line of plaintext  (with ciphertext above)
  63. ;;   %   A comment
  64. ;; Each line in the buffer MUST begin with one of these characters (or
  65. ;; be left blank).  In addition, comments beginning with `%!' are reserved
  66. ;; for checkpoints; see decipher-make-checkpoint & decipher-restore-checkpoint
  67. ;; for more information.
  68. ;;
  69. ;; While the cipher message may contain digits or punctuation, Decipher
  70. ;; mode will ignore these characters.
  71. ;;
  72. ;; The buffer is made read-only so it can't be modified by normal
  73. ;; Emacs commands.
  74. ;;
  75. ;; Decipher supports Font Lock mode.  To use it, you can also add
  76. ;;     (add-hook 'decipher-mode-hook 'turn-on-font-lock)
  77. ;; See the variable `decipher-font-lock-keywords' if you want to customize
  78. ;; the faces used.  I'd like to thank Simon Marshall for his help in making
  79. ;; Decipher work well with Font Lock.
  80.  
  81. ;;; Things To Do:
  82. ;;
  83. ;; Email me if you have any suggestions or would like to help.
  84. ;; But be aware that I work on Decipher only sporadically.
  85. ;;
  86. ;; 1. The consonant-line shortcut
  87. ;; 2. More functions for analyzing ciphertext
  88.  
  89. ;;;===================================================================
  90. ;;; Variables:
  91. ;;;===================================================================
  92.  
  93. (eval-when-compile
  94.   (require 'cl))
  95.  
  96. (defvar decipher-force-uppercase t
  97.   "*Non-nil means to convert ciphertext to uppercase.
  98. Nil means the case of the ciphertext is preserved.
  99. This variable must be set before typing `\\[decipher]'.")
  100.  
  101. (defvar decipher-ignore-spaces nil
  102.   "*Non-nil means to ignore spaces and punctuation when counting digrams.
  103. You should set this to `nil' if the cipher message is divided into words,
  104. or `t' if it is not.
  105. This variable is buffer-local.")
  106. (make-variable-buffer-local 'decipher-ignore-spaces)
  107.  
  108. (defvar decipher-undo-limit 5000
  109.   "The maximum number of entries in the undo list.
  110. When the undo list exceeds this number, 100 entries are deleted from
  111. the tail of the list.")
  112.  
  113. ;; End of user modifiable variables
  114. ;;--------------------------------------------------------------------
  115.  
  116. (defvar decipher-font-lock-keywords
  117.   '(("^:.*"  . font-lock-keyword-face)
  118.     ("^>.*"  . font-lock-string-face)
  119.     ("^%!.*" . font-lock-reference-face)
  120.     ("^%.*"  . font-lock-comment-face)
  121.     ("\\`(\\([a-z]+\\) +\\([A-Z]+\\)"
  122.      (1 font-lock-string-face)
  123.      (2 font-lock-keyword-face))
  124.     ("^)\\([A-Z ]+\\)\\([a-z ]+\\)"
  125.      (1 font-lock-keyword-face)
  126.      (2 font-lock-string-face)))
  127.   "Expressions to fontify in Decipher mode.
  128. Ciphertext uses `font-lock-keyword-face', plaintext uses
  129. `font-lock-string-face', comments use `font-lock-comment-face', and
  130. checkpoints use `font-lock-reference-face'.  You can customize the
  131. display by changing these variables.  For best results, I recommend
  132. that all faces use the same background color.
  133. For example, to display ciphertext in the `bold' face, use
  134.   (add-hook 'decipher-mode-hook
  135.             (lambda () (set (make-local-variable 'font-lock-keyword-face)
  136.                             'bold)))
  137. in your `.emacs' file.")
  138.  
  139. (defvar decipher-mode-map nil
  140.   "Keymap for Decipher mode.")
  141. (if (not decipher-mode-map)
  142.     (progn
  143.       (setq decipher-mode-map (make-keymap))
  144.       (suppress-keymap decipher-mode-map)
  145.       (define-key decipher-mode-map "A" 'decipher-show-alphabet)
  146.       (define-key decipher-mode-map "C" 'decipher-complete-alphabet)
  147.       (define-key decipher-mode-map "D" 'decipher-digram-list)
  148.       (define-key decipher-mode-map "F" 'decipher-frequency-count)
  149.       (define-key decipher-mode-map "M" 'decipher-make-checkpoint)
  150.       (define-key decipher-mode-map "N" 'decipher-adjacency-list)
  151.       (define-key decipher-mode-map "R" 'decipher-restore-checkpoint)
  152.       (define-key decipher-mode-map "U" 'decipher-undo)
  153.       (define-key decipher-mode-map " " 'decipher-keypress)
  154.       (substitute-key-definition 'undo  'decipher-undo
  155.                                  decipher-mode-map global-map)
  156.       (substitute-key-definition 'advertised-undo  'decipher-undo
  157.                                  decipher-mode-map global-map)
  158.       (let ((key ?a))
  159.         (while (<= key ?z)
  160.           (define-key decipher-mode-map (vector key) 'decipher-keypress)
  161.           (incf key)))))
  162.  
  163. (defvar decipher-stats-mode-map nil
  164.   "Keymap for Decipher-Stats mode.")
  165. (if (not decipher-stats-mode-map)
  166.     (progn
  167.       (setq decipher-stats-mode-map (make-keymap))
  168.       (suppress-keymap decipher-stats-mode-map)
  169.       (define-key decipher-stats-mode-map "D" 'decipher-digram-list)
  170.       (define-key decipher-stats-mode-map "F" 'decipher-frequency-count)
  171.       (define-key decipher-stats-mode-map "N" 'decipher-adjacency-list)
  172.       ))
  173.  
  174. (defvar decipher-mode-syntax-table nil
  175.   "Decipher mode syntax table")
  176.  
  177. (if decipher-mode-syntax-table
  178.     ()
  179.   (let ((table (make-syntax-table))
  180.         (c ?0))
  181.     (while (<= c ?9)
  182.       (modify-syntax-entry c "_" table) ;Digits are not part of words
  183.       (incf c))
  184.     (setq decipher-mode-syntax-table table)))
  185.  
  186. (defvar decipher-alphabet nil)
  187. ;; This is an alist containing entries (PLAIN-CHAR . CIPHER-CHAR),
  188. ;; where PLAIN-CHAR runs from ?a to ?z and CIPHER-CHAR is an uppercase
  189. ;; letter or space (which means no mapping is known for that letter).
  190. ;; This *must* contain entries for all lowercase characters.
  191. (make-variable-buffer-local 'decipher-alphabet)
  192.  
  193. (defvar decipher-stats-buffer nil
  194.   "The buffer which displays statistics for thi